#pragma once

#include <linux/mutex_types.h>
#include <linux/lockdep.h>

extern void __mutex_rt_init(struct mutex *lock, const char *name,
                            struct lock_class_key *key);
extern void rt_mutex_base_init(struct rt_mutex_base *rtb);

#define __mutex_init(mutex, name, key)                   \
    do                                                   \
    {                                                    \
        rt_mutex_base_init(&((mutex)->rtmutex));         \
        __mutex_rt_init((mutex), name, key); \
    } while (0)

/**
 * mutex_init - initialize the mutex
 * @mutex: the mutex to be initialized
 *
 * Initialize the mutex to unlocked state.
 *
 * It is not allowed to initialize an already locked mutex.
 */
#define mutex_init(mutex)                      \
    do                                         \
    {                                          \
        static struct lock_class_key __key;    \
                                               \
        __mutex_init((mutex), #mutex, &__key); \
    } while (0)

/*
 * Preempt-RT variant based on rtmutexes.
 */

#define __MUTEX_INITIALIZER(mutexname) \
    {                                  \
        .rtmutex = __RT_MUTEX_BASE_INITIALIZER(mutexname.rtmutex)}

#define DEFINE_MUTEX(mutexname) \
    struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)

void mutex_lock(struct mutex *lock);
void mutex_unlock(struct mutex *lock);
